import React, {
  forwardRef,
  useCallback,
  useContext,
  useEffect,
  useImperativeHandle,
  useMemo,
  useState,
} from 'react';
import { RenderForm } from '@inbiz/render';
import { isBoolean } from 'lodash';
import cls from 'classnames';
import Actions from './Actions';
import TableDrawer from './TableDrawer';
import FullModal, { FullModalProps } from '../FullModal';
import { ActionConfigType, ActionProps, TableModalProps } from '../../interfaces';
import { ActionEnum, EventsMap, ResConst } from '../../shared';
import { InBizTableCtx, InBizTableRefCtx } from '../../context';
import { useModalConfig } from '../../hooks';
import { setComponentsValue } from '../../util';
import '../../style.less';


const getPage = (page?: string) => {
  return page ? page.split(',') : [];
};
const TableModal = (props: TableModalProps, ref: any) => {
  const { state, primaryKey, relationField } = props;
  const { width, maxHeight, minHeight, actions } = useModalConfig();
  const { emit, inbiz, columnConfig } = useContext(InBizTableCtx);
  const { eventsRef, pageRef, modalFormRef, searchRef } = useContext(InBizTableRefCtx);
  const [visible, setVisible] = useState(false);
  const [payload, setPayload] = useState<any>();
  const [extraParam, setExtraParam] = useState<any>();
  const {
    title,
    windowName,
    data,
    page,
    actionType,
    parentAction,
    operationflag,
    openMode = 'modal',
    paramField = '',
  } = payload || {};

  useEffect(() => {
    if (visible) {
      (emit as any)?.(EventsMap.onOpen);
    }
  }, [visible]);

  useImperativeHandle(
    ref,
    () => {
      return {
        showModal: (isShow: boolean, param?: any, action?: any) => {
          if (isShow) {
            const { data = {}, ...actionInfo } = action || { data: {} };
            Promise.resolve(eventsRef?.current.onBeforeOpen?.({ ...data, actionInfo })).then(
              (res) => {
                setVisible(isBoolean(res) ? res : isShow);
                setExtraParam({ ...param, ...(typeof res === 'object' ? res : {}) });
              },
            );
          } else {
            Promise.resolve(eventsRef?.current.onBeforeClose?.() ?? true).then((res) => {
              setVisible(!res);
              if (!res) {
                return;
              }
              (emit as any)?.(EventsMap.onClose);
              setPayload(undefined);
              setExtraParam(undefined);
            });
          }
        },
      };
    },
    [data],
  );
  useEffect(() => {
    if (state) {
      state
        .then((res: any) => {
          if (res && res !== ResConst.other) {
            setPayload(res);
          }
        })
        .catch((err: any) => {
          console.log('dispatch-err>>>', err);
        });
    }
  }, [state]);

  const filterActions = useMemo<ActionConfigType[] | undefined>(() => {
    if (!actions) {
      return;
    }
    const values = [actionType, parentAction];
    const filtered = (actions as ActionProps[])
      .filter(
        (action) => values.includes(action.parentAction) || (actionType === ActionEnum.custom && action.parentAction === operationflag),
      )
      .map((action) => {
        if (
          action.actionType &&
          [ActionEnum.save, ActionEnum.add, ActionEnum.saveAndNew, ActionEnum.serach].includes(
            action.actionType as ActionEnum,
          )
        ) {
          action.buttonType = 'primary';
        }
        if (actionType === ActionEnum.custom) {
          action.windowName = windowName;
          action.page = page;
          action.parentType = actionType;
        }
        return action;
      });
    return [...filtered];
  }, [actions, actionType, parentAction]);
  const [pageName, pageId] = getPage(page);

  // 触发页面初始化成功事件
  const handleInit = useCallback(() => {
    if (pageRef?.current) {
      emit?.('onSubPageInit', pageRef.current.page);
      pageRef.current?.page.on('pageMount', (inbiz: Function) => {
        const { conditions = [], isQueryClick } = searchRef.current;
        if (actionType === ActionEnum.query && isQueryClick) {
          setComponentsValue({ComponentValues: conditions, inbiz})
        }
        return pageRef?.current && emit?.('onSubPageMount', pageRef.current.page);
      });
    }
    pageRef?.current?.page.off('saveData');
    // 页面保存时触发
    pageRef?.current?.page.on('saveData', (_postData: any, res: any) => {
      if (data?.[primaryKey] || extraParam?.[primaryKey]) {
        emit?.('onEdit', res, _postData);
      } else {
        emit?.('onAdd', res, _postData);
      }
    });
  }, [pageId, data, extraParam, searchRef]);

  const queryData = useMemo(() => {

    let _queryData = {
      ...modalFormRef.current,
      id: data?.[primaryKey],
      $primary: primaryKey,
      $relationField: relationField,
      $relationFieldValue: data?.[relationField],
      ...extraParam,
    };
    if (paramField) {
      _queryData[paramField] = data[paramField];
    }
    if ((parentAction && parentAction=== ActionEnum.view)||(actionType=== ActionEnum.view)) {
      _queryData['_viewMode'] = 'look';
    }

    return _queryData;
  }, [data, modalFormRef?.current, paramField, relationField, primaryKey, extraParam]);

  const renderForm = useMemo(() => {
    if (!pageId || !inbiz) {
      return null;
    }
    return (
      <RenderForm
        ref={pageRef}
        key={`${pageId}_${data?.[primaryKey] || extraParam?.[primaryKey]}_${Date.now()}`}
        id={pageName}
        globalSDK={inbiz!.getGlobalSDK?.()}
        queryData={queryData}
        onInit={handleInit}
        type={'page'}
      />
    );
  }, [inbiz, pageId, data?.[primaryKey], payload, extraParam]);

  const modalFooter = useMemo(
    () =>
      filterActions && (
        <div style={{ textAlign: columnConfig?.formItems?.position || 'right' }}>
          <Actions className={'modal-buttons'} actions={filterActions} displayQty={100} pageRef={pageRef} />
        </div>
      ),
    [filterActions],
  );

  const onClose = () => {
    (emit as any)?.(EventsMap.onClick, props.actionType || 'cancel');
    Promise.resolve(eventsRef?.current.onBeforeClose?.() ?? true).then((res) => {
      setVisible(!res);
      if (!res) {
        return;
      }
      (emit as any)?.(EventsMap.onClose);
      setPayload(undefined);
      setExtraParam(undefined);
    });
  };
  const modalProps: FullModalProps = {
    name: extraParam?.actionInfo?.title || title || windowName,
    centered: true,
    closable: false,
    visible,
    style: { maxHeight, minHeight },
    width,
    className: cls('table-modal'),
    onClose,
    transitionName: '',
    maskTransitionName: '',
    footer: modalFooter,
    render: renderForm,
    destroyOnClose: true,
    top: 0,
    move: extraParam?.move
  };

  const drawerProps = {
    title: extraParam?.actionInfo?.title || title || windowName,
    visible,
    openMode,
    actions: filterActions,
    width,
    height: minHeight,
    onClose,
    transitionName: '',
    maskTransitionName: '',
    destroyOnClose: true,
    render: renderForm,
    pageRef
  };

  return 'modal' === openMode ? (
    visible ? (
      <FullModal {...modalProps} />
    ) : null
  ) : visible ? (
    <TableDrawer {...drawerProps} />
  ) : null;
};

export default React.memo(forwardRef(TableModal));
